package com.lottery.game.core.modules.service.app;

import com.lottery.game.common.constants.GameConstants;
import com.lottery.game.common.utils.DateUtils;
import com.lottery.game.common.utils.UUIDUtils;
import com.lottery.game.common.utils.ValidateUtils;
import com.lottery.game.core.modules.entity.game.GameApiLog;
import com.lottery.game.core.modules.entity.game.GameRoom;
import com.lottery.game.core.modules.entity.user.BetLimit;
import com.lottery.game.core.modules.entity.user.GameIssue;
import com.lottery.game.core.modules.entity.user.HuiShui;
import com.lottery.game.core.modules.entity.user.SpecialOdds;
import com.lottery.game.core.modules.entity.user.UserBlncDetail;
import com.lottery.game.core.modules.mapper.BetDao;
import com.lottery.game.core.modules.mapper.RoomDao;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import lombok.extern.slf4j.Slf4j;

/**
 * 游戏服务
 * @author chenye
 * @version 2018-04-25
 */
@Slf4j
@Service
public class BetService {

	@Autowired
	private BetDao betDao;

	@Autowired
	private RoomDao roomDao;


	public List<GameRoom> queryRoomTypeList (){
		return this.roomDao.queryRoomTypeList();
	}

	public GameRoom queryRoomType (GameRoom room){
		return this.roomDao.queryRoomType(room);
	}

	public List<GameRoom> queryRoomList(GameRoom room){
		return this.roomDao.queryUsedRoomList(room);
	}

	public GameRoom queryDownTimeByType(String type) {
	    return this.roomDao.queryDownTimeByType(type);
	}

	/**
	 * 插入游戏期
	 * @param issue
	 */
//    @TxTransaction(isStart = true)
//    @Transactional
	public void addBatchGameIssue(List<GameRoom> roomList, Integer gameTypePlayingTicket, String issue, String issueApi, Date openTime) {
		log.info("---插入游戏期---roomList.size: {}", roomList.size());
		List<GameIssue> list = new ArrayList<GameIssue>();
		for(int i =0; i<roomList.size(); i++) {
			GameIssue gameIssue = new GameIssue();
			gameIssue.setId(UUIDUtils.randomUUID());
			gameIssue.setIssue(issue);
			gameIssue.setGameTypePlayingTicket(gameTypePlayingTicket);
			gameIssue.setIssueApi(issueApi);
			gameIssue.setRoomId(roomList.get(i).getRoomnumber());
			gameIssue.setStatus(GameConstants.GameIssueStatus_Running);
			gameIssue.setOpenTime(openTime);
			list.add(gameIssue);

			log.info("   ----id: {}", gameIssue.getId());
		}

		this.betDao.addGameIssueBatch(list);
	}

    /**
     * 获取房间游戏历史记录
     */
    public List<GameIssue> getRoomGameRecord(String roomId,int start,int pageSize){
        return this.betDao.queryRoomGameIssueHis(roomId,start,pageSize);
    }

    /**
     * 获取回水记录
     */
    public List<HuiShui> getHuiShui(String userId,String roomId,int start,int pageSize){
        return this.betDao.getHuiShui(userId,roomId,start,pageSize);
    }

	/**
	 * 获取游戏期
	 */
	public List<GameIssue> queryGameIssue(GameIssue gameIssue){
		return this.betDao.queryGameIssue(gameIssue);
	}
	/**
	 * 更新为开奖异常
	 * 服务启动时如果有未开奖的记录 则更新为异常记录
	 * @author zhuiyv
	 * @date 2018-06-21
	 */
	public void updateGameIssueError() {
		this.betDao.updateGameIssueError();
	}
	/**
	 * 更新开奖状态
	 * @author zhuiyv
	 * @date 2018-06-21
	 */
	public void updateGameIssueStatus(String status, String currentIssue,String note) {
	    this.betDao.updateGameIssueStatus(status,currentIssue, note);
	}

	public void updateGameIssueClose(String status, String currentIssue) {
        this.betDao.updateGameIssueClose(status,currentIssue);
    }

	public void updateGameIssueResult(String status, String currentIssue,String resultStr,String note) {
		this.betDao.updateGameIssueResult(status,currentIssue,resultStr, note);
	}


	/**
	 * 通过游戏期号获取游戏场次
	 * @param issue    开奖期号
	 * @return List<Map<String, Object>>
	 */
	public List<Map<String, Object>> getGamelistByIssue(String issue) {
		return this.betDao.getGamelistByIssue(issue);
	}
	/**
	 * 通过游戏场次id 获取到所有参加游戏的人，和押注数据
	 * @param gameid
	 * @return
	 */
	public List<Map<String, Object>> getUserListByGameid(String gameid) {
		return this.betDao.getUserListByGameid(gameid);
	}
	/**
	 * 获取房间 游戏赔率
	 *
	 */
	public Map<String, Object> getOddbyRoomNumber(String roomNumber) {
		return this.betDao.getOddbyRoomNumber(roomNumber);
	}

	/**
	 * 记录用户金额和保存余额数据作为一个整体事务
	 */
	@Transactional
	public void saveBetChange(String currentIssue, List<UserBlncDetail> blncChangeList) {
		if(blncChangeList.size()>0) {
			//this.betDao.saveUserMoneyBatch(blncChangeList);
			//代码重构
			for(UserBlncDetail userBlncDetail : blncChangeList) {
				log.info("记录用户金额和保存余额数据,userid==" +userBlncDetail.getUserId()+"========金额变动========="+userBlncDetail.getChangeAmt());
				this.betDao.saveUserMoney2(userBlncDetail);
				this.betDao.updateUserBalance(userBlncDetail.getChangeAmt(),userBlncDetail.getUserId());
			}
		}
		//更新为计算完成状态
		this.betDao.updateGameIssueStatus(GameConstants.GameIssueStatus_Finish, currentIssue, null);
	}
	/**
	 * 检查游戏期次是否可以下注
	 * @param gameIssue
	 * @return
	 */
	public GameIssue checkGameIssue(GameIssue gameIssue) {
		GameIssue queryIssue = gameIssue;
		queryIssue.setStatus(GameConstants.GameIssueStatus_Running);
		List<GameIssue> gameList = this.betDao.queryGameIssue(queryIssue);
		if(gameList!=null && gameList.size() == 1) {
			queryIssue = gameList.get(0);
		} else {
			//传入期次已经不是正在运行状态，返回一个新的
			queryIssue = new GameIssue();
			queryIssue.setRoomId(gameIssue.getRoomId());
			queryIssue.setStatus(GameConstants.GameIssueStatus_Running);
			gameList = this.betDao.queryGameIssue(queryIssue);
			if(gameList != null && gameList.size() == 1) {
				queryIssue = gameList.get(0);
			}
		}
		return queryIssue;

	}
	/**
	 * 查询用户余额 明细信息
	 * @return
	 */
	public List<UserBlncDetail> queryUserBlncDetail(String userId,int start,int pageSize,String startDate,String endDate,String type){
	    List<UserBlncDetail> list = new ArrayList<>();
	    list = this.betDao.queryUserBlncDetail(userId, start, pageSize, startDate, endDate, type);
        return list ;
	}
	public List<UserBlncDetail> queryUserBlncDetailByType(String userId,int start,int pageSize,String startDate,String endDate,String type){
        List<UserBlncDetail> list = new ArrayList<>();
        if(GameConstants.BlanceChangeType_Q_BetAll.equals(type)) {
            list = this.betDao.queryUserBlncDetailWithBet(userId, start, pageSize, startDate, endDate);
        }else  if(GameConstants.BlanceChangeType_Q_InOut.equals(type)) {
            list = this.betDao.queryUserBlncDetailWithInOut(userId, start, pageSize, startDate, endDate);
        }else {
            list = this.betDao.queryUserBlncDetail(userId, start, pageSize, startDate, endDate, type);
        }
        return list ;
    }


	/**
	 * 查询1314特殊赔率
	 * @param specialOdds
	 * @return
	 */
	public SpecialOdds querySpecialOdds(SpecialOdds specialOdds){
	    List<SpecialOdds>  list = this.betDao.querySpecialOdds(specialOdds);
	    if(list!=null&&list.size()>0) {
	        return list.get(0);
	    }else {
	        return null;
	    }
	}

	public BigDecimal queryCurrentIssueBetTotleAmt(String gameId,String userId) {
	    BigDecimal resultAmt = this.betDao.queryCurrentIssueBetTotleAmt(gameId, userId);
	    return ValidateUtils.dealNULL(resultAmt);
	}

    public BigDecimal queryCurrentIssueTypeBetAmt(String gameId,String userId,String betStr) {
        BigDecimal resultAmt = this.betDao.queryCurrentIssueTypeBetAmt(gameId, userId, betStr);
        return ValidateUtils.dealNULL(resultAmt);
    }

    public List<BetLimit> queryLimitByRoomNumber(String roomNumber){
        return this.betDao.queryLimitByRoomNumber(roomNumber);
    }

    public GameRoom queryRoomByBetId(String betId){
        return this.roomDao.queryRoomByBetId(betId);
    }

    public String getHuishuiGuiZe() {
        return this.betDao.getHuishuiGuiZe();
    }
    public  void insertApiLog(GameApiLog apiLog) {
        List<GameApiLog> list = this.betDao.queryGameApiLogByIssueApi(apiLog);
        if(list.size() <= 0) {
        	this.betDao.insertApiLog(apiLog);
        }
    }

    public void tryUpdateIssueOpenTime(GameIssue gameIssue) {
    	this.betDao.tryUpdateIssueOpenTime(gameIssue);
    }

	public void updateOpenTimeByExpect(Integer expect,Date openTime) {
		this.betDao.updateOpenTimeByExpect(expect,openTime);
	}

	public List<GameIssue> queryRunningGameIssue(String roomNumber) {
		GameIssue gameIssue = new GameIssue();
		gameIssue.setRoomId(roomNumber);
		gameIssue.setStatus(GameConstants.GameIssueStatus_Running);
		Date currentTime = new Date();
		log.info("   ----query.currentTime: {}", DateUtils.getDateString(currentTime));
		gameIssue.setCurrentTime(currentTime);
		return this.queryGameIssue(gameIssue);
	}

}
